#include <iostream>
#include <mysql/mysql.h>
#include <cstdio>
#include <string>
#include <cstdlib>

using namespace std;

#define HOST "127.0.0.1"
#define USER "root"
#define DB "demo_db"

namespace Demo
{
    class Mysql
    {
    public:
        Mysql()
        {
            mysql = mysql_init(nullptr); // 1.初始化mysql句柄
            if (mysql == nullptr)
            {
                cout << "mysql_init error!!!" << endl;
                exit(1);
            }
            // 2.连接mysqld == mysql -u root -p ""
            if (mysql_real_connect(mysql, HOST, USER, nullptr, DB, 3306, nullptr, 0) == nullptr)
            {
                cout << "mysql_real_connect error!!!" << endl;
                exit(2);
            }
            if (mysql_set_character_set(mysql, "utf8") != 0) // 3.设置Client字符编码集 == charset=utf8;
            {
                cout << "mysql_set_character_set error!!!" << endl;
                exit(3);
            }
            if (mysql_select_db(mysql, DB)) // 4.选择操作的数据库 == use database;
            {
                cout << "mysql_select_db error!!!" << endl;
                exit(4);
            }
        }

        void addTableData(const string &Instructions) // 添加表数据
        {
            if (mysql_query(mysql, Instructions.c_str()) != 0) // 执行mysql语句
            {
                cout << "addTableData mysql_query error -> " << mysql_error(mysql) << endl;
                exit(5);
            }
        }

        void ModTableData(const string &Instructions) // 修改表数据
        {
            if (mysql_query(mysql, Instructions.c_str()) != 0) // 执行mysql语句
            {
                cout << "ModTableData mysql_query error -> " << mysql_error(mysql) << endl;
                exit(6);
            }
        }

        void DelTableData(const string &Instructions) // 删除表数据
        {
            if (mysql_query(mysql, Instructions.c_str()) != 0) // 执行mysql语句
            {
                cout << "DelTableData mysql_query error -> " << mysql_error(mysql) << endl;
                exit(7);
            }
        }

        void GetTableData(const string &Instructions) // 获取表数据的内容 -- 打印表数据
        {
            if (mysql_query(mysql, Instructions.c_str()) != 0) // 1.执行mysql语句
            {
                cout << "GetTableData mysql_query error -> " << mysql_error(mysql) << endl;
                exit(8);
            }
            MYSQL_RES *res = mysql_store_result(mysql); // 2.将语句执行的结果保存到本地 -- 保存到结果集中(MYSQL_RES)
            if (res == NULL)
            {
                printf("mysql store result error:%s\n", mysql_error(mysql));
                exit(9);
            }
            int row = mysql_num_rows(res);      // 获取结果集行数
            int col = mysql_num_fields(res);    // 获取结果集的列数
            printf("%10s%10s%10s%10s\n", "ID", "年龄", "姓名", "成绩");
            for (int i = 0; i < row; i++)
            {
                MYSQL_ROW row_data = mysql_fetch_row(res); // 获取结果集的一行数据
                for (int i = 0; i < col; i++)
                {
                    printf("%10s", row_data[i]);
                }
                printf("\n");
            }
            mysql_free_result(res); // 释放结果集
        }

        ~Mysql()
        {
            if (mysql != nullptr) // 销毁句柄
                mysql_close(mysql);
        }

    private:
        MYSQL *mysql = nullptr; // 句柄
    };
}

int main()
{
    // api接口参数都是通过mysql指令来对mysqld发起任务
    Demo::Mysql mysql;
    mysql.addTableData("insert into test_tb values(NULL, 18, '张三', 88.88), (NULL, 17, '李四',77);"); // 增
    mysql.ModTableData("update test_tb set age=34 where name='张三';"); // 查改
    mysql.DelTableData("delete from test_tb where name='李四';"); // 删
    mysql.GetTableData("select * from test_tb"); // 获取信息
    return 0;
}